package gui;

import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.swing.AbstractCellEditor;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;

import exceptions.UPException;
import model.Job;
import model.ListManager;

/**
 * CheckBoxEditor class that manages adding volunteers to jobs.
 * @author Doug Hutchens
 * @author Sean Brown
 * @version 1.0
 */

@SuppressWarnings("serial")
public class CheckBoxEditor extends AbstractCellEditor 
                            implements TableCellEditor,
                                       ActionListener {
	
	/** The checkbox that will be selected. */
	
	private JCheckBox my_check_box;
	
	/**  The available jobs table. */
	
	private JTable my_table;
	
	/**  The jobs table that the volunteer is signed up for. */
	
	private JTable my_jobs_table;
	
	/**  The ListManager inistance. */
	
	private ListManager my_mgr;
	
	/**  The available job list. */
	
	private Collection<Job> my_jobs;
	
	/**
	 * Constructor for CheckBoxEditor
	 * @param the_check_box
	 * @param the_avail_table with available jobs.
	 * @param the_lm ListManager
	 * @param the_jobs available jobs.
	 * @param the_jobs_table jobs users is signed up for.
	 */
		
	public CheckBoxEditor(JCheckBox the_check_box,
			              JTable the_avail_table,
			              ListManager the_lm,
			              Collection<Job> the_jobs,
			              JTable the_jobs_table) {
		
		my_check_box = the_check_box;
		my_check_box.addActionListener(this);		
		my_table = the_avail_table;
		my_mgr = the_lm;
		my_jobs = the_jobs;
		my_jobs_table = the_jobs_table;
	}
	
	/**
	 * This method evaluates the action performed on
	 * a checkbox from the from a volunteer and re-initializes
	 * the JTables based on the user selection.
	 */

	
	@Override
	public void actionPerformed(ActionEvent e) {
		
		JCheckBox result = (JCheckBox)e.getSource();
				
		final int job_type = showConfirmAddJob();
		
		if (job_type != -1) {
			try {
				int job_id = (Integer)my_table.getModel().
					      getValueAt(my_table.getSelectedRow(),
	                               12);		
				my_mgr.volunteerForJob(job_id, job_type);
				my_table.getModel().
				         setValueAt(true,
						            my_table.getSelectedRow(),
						            my_table.getSelectedColumn());
				
				Job new_job = my_mgr.findJob(job_id);
				my_jobs = verifyJobs(my_jobs, new_job);	
				
				
			} catch (final UPException upe) {
				my_table.getModel().setValueAt(false,
						                       my_table.
						                       getSelectedRow(),
						                       my_table.
						                       getSelectedColumn());
				
				result.setSelected(false);						
				GUIUtil.errorMessage(new JFrame(), upe.getMessage());
				
			}
		} else {
			
			my_table.getModel().setValueAt(false,
                       my_table.getSelectedRow(),
                       my_table.getSelectedColumn());
			result.setSelected(false);
			
		}		
		
		updateAllTables(my_jobs);
		my_table.revalidate();
		
		
	}
	
	/**
	 * Required override for AbstractCellEditor. 
	 */
	
	@Override
	public Object getCellEditorValue() {
		return this;
	}
	
	/**
	 * Required override for AbstractCellEditor. 
	 */

	@Override
	public Component getTableCellEditorComponent(JTable table,
			                                     Object value,
			                                     boolean isSelected,
			                                     int row,
			                                     int column) {
		return my_check_box;
	}
	
	/**
	 * The dialog box displayed when a user selects to volunteer
	 * for a job.
	 * 
	 * @return int based on the user selection.
	 */
	
	private int showConfirmAddJob() {
		
		
    	int return_val = -1;
    	final List<String> options = new ArrayList<String>();
		options.add("Light"); //0
		options.add("Medium"); //1
		options.add("Heavy"); //2
		final JPanel option_panel = new JPanel(new GridLayout(3,1));
		final ButtonGroup option_group = new ButtonGroup();
		int mnemonic = 0;
		for (String s : options) {
			final JRadioButton j = new JRadioButton(s);
			j.setMnemonic(mnemonic);
			option_group.add(j);
			option_panel.add(j);
			j.setSelected(false);
			mnemonic++;
		}
		return_val = JOptionPane.showOptionDialog(null, option_panel,  
			    "Volunteer Selection", JOptionPane.CANCEL_OPTION,  
			    JOptionPane.QUESTION_MESSAGE, null, null, null);
		if (return_val != JOptionPane.CANCEL_OPTION) {
			return_val = option_group.getSelection().getMnemonic();
		} else {
			return_val = -1;
		}
		return return_val;
    }
	
	/**
	 * Returns a new Collection<Job> list to display in the available
	 * jobs JTable.
	 * 
	 * @param the_existing collection before user selection.
	 * @param the_updated job to put in the collection.
	 * 
	 * @return Collection<Job> to display in available jobs.
	 */
	
	private Collection<Job> verifyJobs(Collection<Job> the_existing,
			                           Job the_updated) {
		Collection<Job> result = new ArrayList<Job>();
		
		for (Job j : the_existing) {
			if (!j.equals(the_updated)) {
				result.add(j);
			} else {
				result.add(the_updated);
			}
		}
		
		return result;
	}
	
	/**
	 * Updates all the tables for the volunteer frame.
	 * @param the_jobs to add in the table.
	 */
	
	private void updateAllTables(Collection<Job> the_jobs) {
		
		VolunteerTableModel model = 
				new VolunteerTableModel(the_jobs,
                         				true,
                		    			my_mgr);
		my_table.setModel(model);
		
		TableColumn column = my_table.getColumnModel().
                getColumn(13);

		final JCheckBox checkBox = new JCheckBox();

		checkBox.setHorizontalAlignment(JCheckBox.CENTER);

		column.setCellEditor(new CheckBoxEditor(checkBox,
                          my_table,
                          my_mgr,
                          the_jobs,
                          my_jobs_table));

		column.setCellRenderer(new DefaultTableCellRenderer() {
			public Component getTableCellRendererComponent(
						JTable my_table,
						Object value,
						boolean isSelected,
						boolean hasFocus,
						int row,
						int column) {
				if (value instanceof Boolean) {
					checkBox.setSelected(((Boolean)value).booleanValue());
				}					
				return checkBox;
			}

		});

		my_jobs_table.setModel(
				new VolunteerTableModel(my_mgr.getUserJobs(),
                  false,
                  my_mgr));

		
	}
	
	

}
